//! @Author: DengLibin
//! @Date: Create in 2024-07-24 17:32:24
//! @Description: jwt

use chrono::{Duration, Utc};
use jsonwebtoken::{decode, encode, Algorithm, DecodingKey, EncodingKey, Header, Validation};
use serde::{Deserialize, Serialize};

use crate::sys::global::{to_global_result, GlobalResult};
const SECRET: &[u8] = b"Aos09lAl0lqazldL";

#[derive(Debug, Serialize, Deserialize)]
pub struct Claims {
    pub sub: String, // 用户标识符
    pub exp: usize,  // 过期时间
}

/// @Author: DengLibin
/// @Date: Create in 2024-07-24 17:33:21
/// @Description: 生成token
/// @param sub: 标识信息
/// @param expire_sec: 过期时间 秒
/// @return: String
pub fn generate_token(sub: String, expire_sec: i64) -> GlobalResult<String> {
    let expiration = Utc::now()
        .checked_add_signed(Duration::seconds(expire_sec))
        .expect("valid timestamp")
        .timestamp() as usize;
    let claims = Claims {
        sub,
        exp: expiration,
    };

    let mut header = Header::new(Algorithm::HS256);
    header.kid = Some("blabla".to_owned());
    let token = encode(&header, &claims, &EncodingKey::from_secret(SECRET.as_ref()));
    to_global_result(token)
}

/// @Author: DengLibin
/// @Date: Create in 2024-07-24 17:44:25
/// @Description: 校验token
pub fn verify_token(token: &str) -> GlobalResult<String> {
    let token_data = decode::<Claims>(
        token,
        &DecodingKey::from_secret(SECRET.as_ref()),
        &Validation::new(Algorithm::HS256),
    );
    let data = to_global_result(token_data)?;
    Ok(data.claims.sub)
}
